package org.sundatagroup.aurora.core.entity.particle;

import java.util.List;

import org.sundatagroup.aurora.core.entity.model.ParticleModel;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
 * 粒子工厂, 创建粒子或者粒子组的工厂
 * 
 * @author Zdream
 * @date 2018-06-08
 * @since 0.2.0
 */
public class ParticleFactory {
	
	public static final JsonParser parser = new JsonParser();

	/**
	 * @param pm
	 *   粒子数据映射
	 * @return
	 *   创建相应的粒子实体
	 * @throws IllegalArgumentException
	 *   粒子数据无法识别、非法等情况下
	 */
	public static Particle build(ParticleModel pm) throws IllegalArgumentException {
		JsonObject rule = parser.parse(pm.getRule()).getAsJsonObject();
		
		if (rule.get("project") != null) {
			if (rule.get("index") != null) {
				return IndexParticle.of(pm);
			}
			
			if (rule.get("module") != null) {
				return ModuleParticle.of(pm);
			}
			
			return ProjectParticle.of(pm);
		}
		
		throw new IllegalArgumentException("Particle 无法创建, 无法识别 rule: " + rule);
	}
	
	/**
	 * @param pid
	 *   工程 ID
	 * @param pm
	 *   粒子数据映射列表
	 * @return
	 *   创建相应的粒子实体组, 过滤掉与 pid 不相符的粒子
	 * @throws IllegalArgumentException
	 *   pms 存在粒子数据无法识别、非法等情况下
	 */
	public static ParticleGroup buildGroup(int pid, List<ParticleModel> pms) throws IllegalArgumentException {
		ParticleGroup pg = new ParticleGroup(pid);
		final JsonParser parser = ParticleFactory.parser;
		
		pms.forEach((pm) -> {
			JsonObject rule = parser.parse(pm.getRule()).getAsJsonObject();
			
			int ppid = rule.get("project").getAsInt();
			if (pid != ppid) {
				return;
			}
			
			Particle p = build(pm);
			ParticleRule[] rules = p.rules();
			
			if (rules.length == 1) {
				switch (rules[0]) {
				case PROJECT:
					pg.pp = (ProjectParticle) p;
					break;
				case MODULE: {
					ModuleParticle mp = (ModuleParticle) p;
					pg.mps.put(mp.getModule(), mp);
				} break;
					
				case INDEX: {
					IndexParticle ip = (IndexParticle) p;
					pg.ips.put(ip.getIndex(), ip);
				} break;
				}
			} else {
				// 暂时无法处理
			}
		});
		
		return pg;
	}

}
